import yfinance as yf
import numpy as np
import pandas as pd
from pandas_datareader import data as pdr
from matplotlib import pyplot as plt
import plotly.graph_objects as go
import warnings
import statistics as stats
warnings.filterwarnings("ignore")
start_date = "2023-01-05"
end_date = "2023-12-12"
tickers = ["ARGT","AVTR","HCC","DHR","TMF","VZ","USO","TTWO","SHY","MBB","GLD","EWZ","EA","CTLT","SPY"]
wts = [
0.7
,0.01
,0.3
,0.01
,0.24
,0.02
,0.23
,0.01
,0.10
,0.13
,0.7
,0.7
,0.01
,0.01
,0.000
]
yf.pdr_override()
price_data = pdr.get_data_yahoo(tickers,
start = start_date,
end = end_date)
[*********************100%***********************] 15 of 15 completed
price_data = price_data['Adj Close']
ret_data = price_data.pct_change()[1:]
weighted_returns = (wts * ret_data)
weighted_returns = weighted_returns.reset_index()
weighted_returns.head()
| Date | ARGT | AVTR | CTLT | DHR | EA | EWZ | GLD | HCC | MBB | SHY | SPY | TMF | TTWO | USO | VZ | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2023-01-06 | 0.019792 | -0.000276 | 0.009682 | -0.000107 | -0.001521 | 0.000771 | 0.004303 | 0.000375 | 0.001292 | 0.000496 | 0.016052 | 0.038017 | -0.000114 | 0.000008 | 0.0 |
| 1 | 2023-01-09 | 0.011195 | 0.000294 | 0.003273 | 0.000101 | 0.000542 | -0.000148 | 0.000516 | -0.000292 | 0.000295 | 0.000128 | -0.000397 | 0.010190 | 0.000033 | 0.000162 | -0.0 |
| 2 | 2023-01-10 | 0.004446 | 0.000392 | -0.000498 | 0.000464 | -0.000290 | 0.000520 | 0.000845 | 0.000113 | -0.000410 | -0.000112 | 0.004909 | -0.033223 | 0.000041 | 0.000003 | 0.0 |
| 3 | 2023-01-11 | 0.015368 | 0.000331 | 0.008482 | 0.000259 | 0.004045 | 0.000458 | -0.000158 | 0.000021 | 0.000697 | 0.000112 | 0.008854 | 0.032445 | -0.000026 | 0.000326 | -0.0 |
| 4 | 2023-01-12 | 0.020489 | -0.000023 | -0.000667 | -0.000055 | 0.000590 | 0.000170 | 0.002661 | -0.000068 | 0.000702 | 0.000287 | 0.002549 | 0.040310 | -0.000092 | 0.000082 | 0.0 |
# Calculate portfolio returns
port_ret = weighted_returns.drop("Date", axis=1).sum(axis=1)
# axis =1 tells pandas we want to add
cumulative_ret = ((port_ret + 1).cumprod()) - 1
fig1 = go.Figure() # go object
MHF = cumulative_ret
SPY = ((ret_data["SPY"] + 1).cumprod()) - 1
fig1.add_trace(go.Scatter(x=weighted_returns["Date"],y=MHF, name='Valatility Return',
line=dict(color='royalblue', width=3,)))
fig1.add_trace(go.Scatter(x=weighted_returns["Date"], y=SPY, name='SPY',
line=dict(color='green', width=3,)))
# Edit the layout
fig1.update_layout(title=f'Mock Hedgefund {(MHF.tail(1).values *100).round(2)}% vs SPY {(SPY.tail(1).values *100).round(2)}% - 2023',
xaxis_title='Year',
yaxis_title='Cumulative Return', width=1000, height=800,)
fig1.show()
Alpha = (MHF.tail(1).values *100).round(2) - (SPY.tail(1).values *100).round(2)
Beta = stats.covariance(MHF, SPY) / stats.variance(SPY)
# Calculate the Sharpe Ratio
sharpe_ratio = np.mean(MHF) / np.std(MHF)
# Annualize the Sharpe Ratio
annual_factor = np.sqrt(252) # Use 252 for daily returns, 52 for weekly returns, 12 for monthly returns
sharpe_ratio_annu = sharpe_ratio * annual_factor
Alpha
alpha_values = []
asset_names = []
# Calculate Alpha for each asset
for asset in tickers:
asset_returns = ret_data[asset]
risk_free_rate = 0.00
excess_return = asset_returns - risk_free_rate
alpha = (excess_return.mean() * 252) * 100 # % Annualized Alpha
asset_names.append(asset)
alpha_values.append(alpha)
# Create a df to hold Asset and Alpha values
alpha_df = pd.DataFrame({'Asset': asset_names, 'Alpha': alpha_values})
Beta
beta_values = []
# Calculate Beta for each asset
for asset in tickers:
asset_returns = ret_data[asset]
covar = stats.covariance(asset_returns, SPY)
var = stats.variance(SPY)
beta = covar / var
beta_values.append(beta)
# Create a df to hold Asset and Beta values
beta_df = pd.DataFrame({'Asset': tickers, 'Beta': beta_values})
Plot Alpha
fig = go.Figure()
fig.add_trace(go.Scatter(
x=alpha_values, y=asset_names,
name='Alpha',
mode='markers',
marker_color= alpha_values
)
)
fig.update_layout(title='Alpha| Asset vs. Benchmark(SPY) for Portfolio Assets - 2023',
yaxis_title='Ticker', width=1000, height=800,
xaxis_title='Alpha Values')
fig.update_traces(mode='markers', marker_line_width=1, marker_size=15)
fig.show()
Plot Beta
fig = go.Figure()
fig.add_trace(go.Scatter(
x=beta_values, y=tickers,
name='Beta',
mode='markers',
marker_color= beta_values
)
)
fig.update_layout(title='Beta| Asset vs. Benchmark(SPY) for Portfolio Assets - 2023',
yaxis_title='Ticker', width=1000, height=800,
xaxis_title='Beta Values')
fig.update_traces(mode='markers', marker_line_width=1, marker_size=15)
fig.show()
Metrics
print(f'Annualized Sharpe Ratio (2023): {round(sharpe_ratio_annu, 2)}%')
Annualized Sharpe Ratio (2023): 39.72%
print(f'2023 Yearly Alpha: {round(Alpha[0], 2)}%')
2023 Yearly Alpha: 4.59%
print(f'2023 Yearly Beta: {round(Beta, 2)}')
2023 Yearly Beta: 0.54